﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using YAPL.Language.Core;
using YAPL.Util;

namespace YAPL.Language.Compiler.CodeGen.ReflectionEmitGenerator.AstGen.Helpers {
	public static class ILGeneratorScopeExtensions {

		public static LocalBuilder EmitCreateAndSaveScope(this ILGenerator ilGen) {
			var scopeCtor = typeof(Scope).GetConstructor(Type.EmptyTypes);
			ilGen.Emit(OpCodes.Newobj, scopeCtor);
			var scopeVar = ilGen.DeclareLocal(typeof (Scope));
			ilGen.Emit(OpCodes.Stloc, scopeVar);
			return scopeVar;
		}

		public static void EmitPrepareScopeParameter(this ILGenerator ilGen, LocalBuilder scopeVar, string key) {
			var setItemMethod = typeof(Scope).GetIndexerSetMethod(new[] { typeof(String) });
			ilGen.Emit(OpCodes.Ldloc, scopeVar);
			ilGen.Emit(OpCodes.Ldstr, key);
			ilGen.Emit(OpCodes.Ldloc_0);
			ilGen.Emit(OpCodes.Callvirt, setItemMethod);
		}

		public static void EmitSetLocalScopeVariable(this ILGenerator ilGen, string key) {
			var setItemMethod = typeof(Scope).GetIndexerSetMethod(new[] { typeof(String) });
			ilGen.Emit(OpCodes.Ldarg_1);
			ilGen.Emit(OpCodes.Ldstr, key);
			ilGen.Emit(OpCodes.Ldloc_0);
			ilGen.Emit(OpCodes.Callvirt, setItemMethod);
			ilGen.Emit(OpCodes.Ldloc_0);
		}

		public static void EmitGetLocalVariableFromScope(this ILGenerator ilGen, string key) {
			var getItemMethod = typeof (Scope).GetIndexerGetMethod(new[] {typeof (String)});
			ilGen.Emit(OpCodes.Ldarg_1);
			ilGen.Emit(OpCodes.Ldstr, key);
			ilGen.Emit(OpCodes.Callvirt, getItemMethod);
		}

	}
}
